package timetabling;

import generalEvolutionaryAlgorithm.EABlackBoxFunction;
import generalEvolutionaryAlgorithm.EAInstance;
import generalEvolutionaryAlgorithm.EAResult;

import java.util.ArrayList;

public class TimetablingInstance implements EAInstance {
	private EABlackBoxFunction function;
	private EAResult result = null;
	private int timeForEvent[];
	private int roomForEvent[];
	private int rooms, events;
	public TimetablingInstance(EABlackBoxFunction function, int[] timeForEvent, int[] roomForEvent, int rooms){
		this.function = function;
		this.timeForEvent = timeForEvent;
		this.roomForEvent = roomForEvent;
		this.rooms = rooms;
		this.events = timeForEvent.length;
	}
	
	@Override
	public EAResult getResult() {
		return result;
	}

	@Override
	public void calculateResult() {
		result = function.evaluate(this);
	}

	@Override
	public String toString(){
		String days  = "|    MONDAY |   TUESDAY | WEDNESDAY |  THURSDAY |    FRIDAY |";
		String delim = "+-----------+-----------+-----------+-----------+-----------+";
		String empty =  "           ";
		String resultString = delim;
		int eventInRoomAtTime[][] = new int[rooms][45];
		for(int room = 0; room < rooms; room++){
			for(int t = 0; t < 45; t++){
				eventInRoomAtTime[room][t] = -1;
			}
		}
		for(int event = 0; event < events; event++){
			int room = roomForEvent[event];
			if(room == -1)continue;
			int time = timeForEvent[event];
			switch(eventInRoomAtTime[room][time]){
			case -1:
				eventInRoomAtTime[room][time] = event;
				break;
			case -2:
				break;
			default:
				eventInRoomAtTime[room][time] = -2;
			}
		}
		ArrayList<String> resList = new ArrayList<String>();
		resList.add(delim);
		for(int room = 0; room < rooms; room++){
			resList.add(days);
			resultString = resultString + "\n" + days;
			resList.add(delim);
			resultString = resultString + "\n" + delim;
			String nextTable[] = new String[9];
			for(int i = 0; i < 9; i++)nextTable[i] = "|";
			for(int day = 0; day < 5; day++){
				for(int h = 0; h < 9; h++){
					String cur = " ";
					switch(eventInRoomAtTime[room][day*9+h]){
					case -1:
						break;
					case -2:
						cur = cur + "MORE";
						break;
					default:
						cur = cur + eventInRoomAtTime[room][day*9+h];
					}
					cur = cur + empty.substring(0, empty.length() - cur.length()) + "|";
					nextTable[h] = nextTable[h] + cur;
				}
			}
			for(String s: nextTable){
				resList.add(s);
				resultString = resultString + "\n" + s;
			}
			resList.add(delim);
			resultString = resultString + "\n" + delim;
		}
		while(resList.size() > 1){
			ArrayList<String> temp = new ArrayList<String>();
			for(int i = 0; i < resList.size(); i += 2){
				if(i+1 < resList.size()){
					temp.add(resList.get(i) + "\n" + resList.get(i+1));
				}
			}
			resList = temp;
		}
//		return "\n" + resList.get(0) + "\n";
		return "\n" + resultString + "\n";
	}

	public int[] getTimeForEvent() {
		return timeForEvent.clone();
	}

	public int[] getRoomForEvent() {
		return roomForEvent.clone();
	}
	
	public EABlackBoxFunction getFunction(){
		return function;
	}
	
	public String getDataString(){
		String data = "" + rooms + " " + events + "\n";
		for(int event = 0; event < events; event++){
			data = data + roomForEvent[event] + " "  + timeForEvent[event] + "\n";
		}
		return data;
	}
}
